#pragma once
#include <string>
const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";
std::string Encode(const std::string& content)
{
    std::string package;
    package += std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;
    return package;
}
bool Decode(std::string& package, std::string* out)
{
    //7\n10 + 20\n
    size_t pos = package.find(protocol_sep);
    if(pos == std::string::npos)  return false;
    std::string len_string = package.substr(0, pos);
    size_t len = std::stoi(len_string);

    size_t total_len = len + 2 + len_string.size();
    if(total_len > package.size())  return false;

    
    *out = package.substr(pos + 1, len);

    //移除报文
    package.erase(0, total_len);
    return true;
}
class Request
{
public:
    Request()
    {}
    Request(int data1, int data2, char op):x(data1),y(data2),oper(op)
    {}
    ~Request()
    {}
public:
    
    void Serialize(std::string* out)
    {
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += oper;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
    }
    bool Deserialize(std::string& content)
    {
        //"x + y"
        size_t left = content.find(blank_space_sep);
        if(left == std::string::npos)  return false;
        std::string data1 = content.substr(0, left);
      
        size_t right = content.rfind(blank_space_sep);
        if(right != left + 2)  return false;
        std::string data2 = content.substr(right);

        x = std::stoi(data1);
        y = std::stoi(data2);
        oper = content[left+1];
        return true;

    }
public:
    int x;
    int y;
    char oper;
};


class Response
{
public:
    Response()
    {}
    Response(int res, int code):result(res),exitcode(code)
    {}
    ~Response()
    {}
public:
    void Serialize(std::string* out)
    {
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(exitcode);
        *out = s;
    }
    bool Deserialize(std::string& content)
    {
        //"20 0"
        size_t pos = content.find(blank_space_sep);
        if(pos == std::string::npos)  return false;
        std::string result_string = content.substr(0, pos);
        std::string exitcode_string = content.substr(pos + 1);

        result = std::stoi(result_string);
        exitcode = std::stoi(exitcode_string);
        return true;
    }
public:
    int result;
    int exitcode;
};